package com.liuyk.commonlib.network;

import android.text.TextUtils;

import com.liuyk.commonlib.App;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;

import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

public final class NetBuilder {
    private String httpsHostName;

    private String mServerUrl;

    private Headers mHeaders;

    private final List<Interceptor> interceptors;

    private NetBuilder() {
        interceptors = new ArrayList<>();
    }

    public List<Interceptor> getInterceptors() {
        return interceptors;
    }

    public String getHttpsHostName() {
        return httpsHostName;
    }

    public void setHttpsHostName(String httpsHostName) {
        this.httpsHostName = httpsHostName;
    }

    public Headers getHeaders() {
        return mHeaders;
    }

    public void setHeaders(Headers mHeaders) {
        this.mHeaders = mHeaders;
    }

    public final static class Builder {
        NetBuilder netBuilder = new NetBuilder();

        public Builder(String url) {
            netBuilder.mServerUrl = url;
        }

        public Builder setHttpsHostName(String httpsHostName) {
            netBuilder.setHttpsHostName(httpsHostName);
            return this;
        }

        public Builder setHeaders(Headers headers) {
            netBuilder.setHeaders(headers);
            return this;
        }

        public Builder addInterceptor(Interceptor interceptor) {
            if (interceptor != null) {
                netBuilder.interceptors.add(interceptor);
            }
            return this;
        }

        public Builder addInterceptors(List<Interceptor> interceptors) {
            if (interceptors != null && !interceptors.isEmpty()) {
                netBuilder.interceptors.addAll(interceptors);
            }
            return this;
        }

        public <T> T build(final Class<T> clz, int timeout) {
            return netBuilder.create(clz, timeout);
        }

        public NetBuilder getNetBuilder() {
            return netBuilder;
        }

        public ApiInit create() {
            return ApiInit.getInstance();
        }
    }

    public <T> T create(final Class<T> clz, int timeout) throws IllegalArgumentException {

        if (timeout < 0) {
            throw new IllegalArgumentException("timeout must > 0");
        }
        Retrofit.Builder builder = new Retrofit.Builder();
        Retrofit retrofit = builder
                .client(wrapperOkHttpClient(timeout))
                .addConverterFactory(GsonConverterFactory.create())
                //增加返回值为Observable<T>的支持
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .baseUrl(mServerUrl)
                .build();
        return retrofit.create(clz);
    }

    private OkHttpClient wrapperOkHttpClient(int timeout) {
        OkHttpClient.Builder builder = new OkHttpClient.Builder().addInterceptor(new Interceptor() {

            @Override
            public Response intercept(Chain chain) throws IOException {
                Request request = chain.request();
                request = wrapRequest(request);
                return chain.proceed(request);
            }
        }).connectTimeout(timeout, TimeUnit.SECONDS)
                .readTimeout(timeout, TimeUnit.SECONDS);

        if (!getInterceptors().isEmpty()) {
            for (Interceptor interceptor : getInterceptors()) {
                builder.addInterceptor(interceptor);
            }
        }

        if (mServerUrl.startsWith("https")) {
            builder.hostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    boolean verify = true;
                    if (!TextUtils.isEmpty(getHttpsHostName())) {
                        //用来忽略，指定域名下的证书，暂时没有用到
                        verify = HttpsURLConnection.getDefaultHostnameVerifier().verify(getHttpsHostName(), session);
                    }
                    return verify;
                }
            });
        }
        try {
            SSLSocketFactory ssl = SSLSocketFactoryUtils.getSSLSocketFactory_Certificate(App.context, "");
            if (ssl != null) {
                builder.sslSocketFactory(ssl,
                        new SSLSocketFactoryUtils.MyX509TrustManager(App.context, ""));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return builder.build();
    }

    //包装request请求，增加一些通用的参数
    private Request wrapRequest(Request request) {
        Request req;
        Headers headers = getHeaders();
        Request.Builder builder = request.newBuilder();
        //已设置header
        if (headers != null) {
            Map<String, String> builderHeaders = headers.builderHeaders();
            builder.headers(okhttp3.Headers.of(builderHeaders)).build();
        }
        builder.addHeader("os", "android");
        req = builder.build();
        return req;
    }

}
